//
//  RadioButton.m
//
//  Created by Sergey Nikitenko on 3/5/13.
//  Copyright 2013 Sergey Nikitenko. All rights reserved.
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

#import "RadioButton.h"

@interface RadioButton()
{
    NSMutableArray* _sharedLinks;
}
@end

@implementation RadioButton

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        if(![[self allTargets] containsObject:self]) {
            [super addTarget:self action:@selector(onTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
        }
    }
    return self;
}

-(void) awakeFromNib
{
    if(![[self allTargets] containsObject:self]) {
        [super addTarget:self action:@selector(onTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
    }
}

-(void) addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
{
    // 'self' should be the first target
    if(![[self allTargets] containsObject:self]) {
        [super addTarget:self action:@selector(onTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
    }
    [super addTarget:target action:action forControlEvents:controlEvents];
}

-(void) onTouchUpInside
{
    [self setSelected:YES distinct:YES sendControlEvent:YES];
}

-(void) setGroupButtons:(NSArray *)buttons
{
    if(!_sharedLinks) {
        for(RadioButton* rb in buttons) {
            if(rb->_sharedLinks) {
                _sharedLinks = rb->_sharedLinks;
                break;
            }
        }
        if(!_sharedLinks) {
            _sharedLinks = [[NSMutableArray alloc] initWithCapacity:[buttons count]+1];
        }
    }

    BOOL (^btnExistsInList)(NSArray*, RadioButton*) = ^(NSArray* list, RadioButton* rb){
        for(NSValue* v in list) {
            if([v nonretainedObjectValue]==rb) {
                return YES;
            }
        }
        return NO;
    };

    if(!btnExistsInList(_sharedLinks, self)) {
        [_sharedLinks addObject:[NSValue valueWithNonretainedObject:self]];
    }

    for(RadioButton* rb in buttons) {
        if(rb->_sharedLinks!=_sharedLinks) {
            if(!rb->_sharedLinks) {
                rb->_sharedLinks = _sharedLinks;
            } else {
                for(NSValue* v in rb->_sharedLinks) {
                    RadioButton* vrb = [v nonretainedObjectValue];
                    if(!btnExistsInList(_sharedLinks, vrb)) {
                        [_sharedLinks addObject:v];
                        vrb->_sharedLinks = _sharedLinks;
                    }
                }
            }
        }
        if(!btnExistsInList(_sharedLinks, rb)) {
            [_sharedLinks addObject:[NSValue valueWithNonretainedObject:rb]];
        }
    }
}

-(NSArray*) groupButtons
{
    if([_sharedLinks count]) {
        NSMutableArray* buttons = [[NSMutableArray alloc] initWithCapacity:[_sharedLinks count]];
        for(NSValue* v in _sharedLinks) {
            [buttons addObject:[v nonretainedObjectValue]];
        }
        return buttons;
    }
    return nil;
}

-(RadioButton*) selectedButton
{
    if([self isSelected]) {
        return self;
    } else {
        for(NSValue* v in _sharedLinks) {
            RadioButton* rb = [v nonretainedObjectValue];
            if([rb isSelected]) {
                return rb;
            }
        }
    }
    return nil;
}

-(void) setSelected:(BOOL)selected
{
    [self setSelected:selected distinct:YES sendControlEvent:NO];
}

-(void) setButtonSelected:(BOOL)selected sendControlEvent:(BOOL)sendControlEvent
{
    BOOL valueChanged = (self.selected != selected);
    [super setSelected:selected];
    if(valueChanged && sendControlEvent) {
        [self sendActionsForControlEvents:UIControlEventValueChanged];
    }
}

-(void) setSelected:(BOOL)selected distinct:(BOOL)distinct sendControlEvent:(BOOL)sendControlEvent
{
    [self setButtonSelected:selected sendControlEvent:sendControlEvent];

    if( distinct && (selected || [_sharedLinks count]==2) )
    {
        selected = !selected;
        for(NSValue* v in _sharedLinks) {
            RadioButton* rb = [v nonretainedObjectValue];
            if(rb!=self) {
                [rb setButtonSelected:selected sendControlEvent:sendControlEvent];
            }
        }
    }
}

-(void) deselectAllButtons
{
    for(NSValue* v in _sharedLinks) {
        RadioButton* rb = [v nonretainedObjectValue];
        [rb setButtonSelected:NO sendControlEvent:NO];
    }
}

-(void) setSelectedWithTag:(NSInteger)tag
{
    if(self.tag == tag) {
        [self setSelected:YES distinct:YES sendControlEvent:NO];
    } else {
        for(NSValue* v in _sharedLinks) {
            RadioButton* rb = [v nonretainedObjectValue];
            if(rb.tag == tag) {
                [rb setSelected:YES distinct:YES sendControlEvent:NO];
                break;
            }
        }
    }
}

- (void)dealloc
{
    for(NSValue* v in _sharedLinks) {
        if([v nonretainedObjectValue]==self) {
            [_sharedLinks removeObjectIdenticalTo:v];
            break;
        }
    }
}


@end
